package com.hunan.yllxy.config.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.firewall.HttpFirewall;
import org.springframework.security.web.firewall.StrictHttpFirewall;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsUtils;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import java.time.Duration;

/**
 * @Author: 刘华
 * @Date: 2021/3/31 15:51
 * @Version 1.0
 */
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    AuthenticationAccessDeniedHandler authenticationAccessDeniedHandler;
    @Autowired
    MyAuthenticationFailureHandler myAuthenticationFailureHandler;
    @Autowired
    MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;
    @Autowired
    LoginAuthenticationEntryPoint loginAuthenticationEntryPoint;
    @Autowired
    MyLogoutSuccessHandler myLogoutSuccessHandler;
    @Autowired
    UserDetailsService userService;
    @Autowired
    JwtAuthencationTokenFilter jwtAuthencationTokenFilter;
    @Autowired
    private ValidateCodeFilter validateCodeFilter;

    @Override
    public void configure(WebSecurity web) throws Exception {
        //不拦截
        web.ignoring().antMatchers(
                "/api/opening/**",
//                "/api/login/**",
                "/static/**", "/swagger-ui/**", "/swagger-ui.html",
                "/swagger-resources/**",
                "/v2/api-docs",
                "/v3/api-docs",
                "/doc.html",
                "/favicon.ico",
                "/webjars/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //不验证的接口/captcha  /api/email/getCode
        http.authorizeRequests().
                requestMatchers(CorsUtils::isPreFlightRequest).
                permitAll().
                antMatchers().permitAll().anyRequest().authenticated()
                .and()
                .headers().frameOptions().disable().and()
                .formLogin().loginProcessingUrl("/login").permitAll()
                //MyAuthenticationFailureHandler implements AuthenticationFailureHandler
                .failureHandler(myAuthenticationFailureHandler)
                //MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler
                .successHandler(myAuthenticationSuccessHandler)
                //MyLogoutSuccessHandler implements LogoutSuccessHandler
                .and().logout().logoutSuccessHandler(myLogoutSuccessHandler).permitAll()
                .and()
                .cors().and()
//                .cors().configurationSource(corsConfigurationSource()).and()
                .csrf()
                .disable()
                .exceptionHandling().accessDeniedHandler(authenticationAccessDeniedHandler).authenticationEntryPoint(loginAuthenticationEntryPoint)
                .and()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        http.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class);
        http.addFilterBefore(jwtAuthencationTokenFilter, UsernamePasswordAuthenticationFilter.class);

    }


    @Bean
    public HttpFirewall allowUrlEncodedSlashHttpFirewall() {
        StrictHttpFirewall firewall = new StrictHttpFirewall();
        //此处可添加别的规则,目前只设置 允许双 //
        firewall.setAllowUrlEncodedDoubleSlash(true);
        return firewall;
    }

    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.addAllowedOriginPattern("*");
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.addExposedHeader("token");
        corsConfiguration.addExposedHeader("uuid");
        corsConfiguration.setMaxAge(Duration.ofHours(1));
        UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
        urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
        return new CorsFilter(urlBasedCorsConfigurationSource);
    }

//    @Override
//    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        auth.authenticationProvider(this.loginValidateAuthenticationProvider);
//    }

//    @Bean
//    CorsConfigurationSource corsConfigurationSource() {
//        CorsConfiguration corsConfiguration = new CorsConfiguration();
//        // 1允许任何域名使用
//        corsConfiguration.addAllowedOrigin("*");
//        // 2允许任何头
//        corsConfiguration.addAllowedHeader("*");
//        // 3允许任何方法（post、get等）
//        corsConfiguration.addAllowedMethod("*");
////        corsConfiguration.setAllowCredentials(true);
//        corsConfiguration.addExposedHeader("token");
//        corsConfiguration.addExposedHeader("uuid");
//        corsConfiguration.setMaxAge(3600L);
//        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
//        source.registerCorsConfiguration("/**", corsConfiguration);
//        return source;
//    }

//    @Bean
//    CorsConfigurationSource corsConfigurationSource() {
//        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
//        CorsConfiguration configuration = new CorsConfiguration();
//        configuration.setAllowCredentials(true);
//        configuration.setAllowedOrigins(Collections.singletonList("*"));
//        configuration.setAllowedMethods(Collections.singletonList("*"));
//        configuration.setAllowedHeaders(Collections.singletonList("*"));
//        configuration.addExposedHeader("token");
//        configuration.addExposedHeader("uuid");
////        configuration.setMaxAge(Duration.ofHours(1));
//        configuration.setMaxAge(3600L);
//        source.registerCorsConfiguration("/**", configuration);
//        return source;
//    }


    /**
     * 认证管理器
     *
     * @return
     * @throws Exception
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}
